package com.mlethe.library.recyclerview.decoration;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.mlethe.library.recyclerview.listener.ItemDecorationListener;

/**
 * 水平分割线
 *
 * @author Mlethe
 * @date 2018/1/11
 */
public class LinearItemDecoration extends RecyclerView.ItemDecoration {

    private Context mContext;
    private Drawable mDivider;
    private int size;
    private int mOrientation = -1;
    private int marginLeft = 0, marginRight = 0;
    private boolean isShowLeft, isShowTop, isShowRight, isShowBottom, isShowLine = true;

    private ItemDecorationListener mItemDecorationListener;

    public LinearItemDecoration(Context context) {
        mContext = context.getApplicationContext();
        size = dp2px(0.5f);
    }

    /**
     * 设置drawable
     *
     * @param drawableId
     */
    public LinearItemDecoration setDrawable(@DrawableRes int drawableId) {
        return setDrawable(ContextCompat.getDrawable(mContext, drawableId));
    }

    /**
     * 设置drawable
     *
     * @param drawable
     */
    public LinearItemDecoration setDrawable(Drawable drawable) {
        mDivider = drawable;
        return this;
    }

    /**
     * 设置颜色
     *
     * @param colorRes
     */
    public LinearItemDecoration setColor(@ColorRes int colorRes) {
        return setColorInt(ContextCompat.getColor(mContext, colorRes));
    }

    /**
     * 设置颜色
     *
     * @param color
     */
    public LinearItemDecoration setColorInt(@ColorInt int color) {
        mDivider = new ColorDrawable(color);
        return this;
    }

    /**
     * 设置颜色
     *
     * @param colorString
     */
    public LinearItemDecoration setColor(String colorString) {
        return setColorInt(Color.parseColor(colorString));
    }

    /**
     * 设置分割线大小
     *
     * @param size dp
     * @return
     */
    public LinearItemDecoration setSize(float size) {
        return setSize(dp2px(size));
    }

    /**
     * 设置分割线大小
     *
     * @param size px
     * @return
     */
    public LinearItemDecoration setSize(int size) {
        this.size = size;
        return this;
    }

    /**
     * 设置两边的Margin
     *
     * @param left  dp
     * @param right dp
     */
    public LinearItemDecoration setMargin(float left, float right) {
        return setMargin(dp2px(left), dp2px(right));
    }

    /**
     * 设置两边的Margin
     *
     * @param left  px
     * @param right px
     */
    public LinearItemDecoration setMargin(int left, int right) {
        this.marginLeft = left;
        this.marginRight = right;
        return this;
    }

    /**
     * 是否显示线
     *
     * @param show true 显示，false 不显示
     * @return
     */
    public LinearItemDecoration setLineShow(boolean show) {
        isShowLine = show;
        return this;
    }

    /**
     * 四周是否显示分割线
     *
     * @param left   true 显示，false 不显示
     * @param top    true 显示，false 不显示
     * @param right  true 显示，false 不显示
     * @param bottom true 显示，false 不显示
     * @return
     */
    public LinearItemDecoration setAroundShow(boolean left, boolean top, boolean right, boolean bottom) {
        this.isShowLeft = left;
        this.isShowTop = top;
        this.isShowRight = right;
        this.isShowBottom = bottom;
        return this;
    }

    /**
     * 设置自定义分割线
     *
     * @param itemDecorationListener
     * @return
     */
    public LinearItemDecoration setItemDecorationListener(ItemDecorationListener itemDecorationListener) {
        this.mItemDecorationListener = itemDecorationListener;
        return this;
    }

    /**
     * dp转px
     *
     * @param dp
     * @return
     */
    private int dp2px(float dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics());
    }

    /**
     * 设置条目周边的偏移量
     *
     * @param outRect
     * @param view
     * @param parent
     * @param state
     */
    @SuppressLint("WrongConstant")
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (size == 0) {
            return;
        }
        // 代表在每个底部的位置留出10px来绘制分割线 最后一个位置不需要分割线
        int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
        if (position < 0) {
            return;
        }
        int itemCount = parent.getAdapter().getItemCount();
        if (position >= itemCount) {
            return;
        }
        if (mItemDecorationListener != null) {
            int startPosition = mItemDecorationListener.getStart();
            int dataSize = mItemDecorationListener.getDrawCount();
            if (startPosition >= 0 && position >= startPosition && dataSize > 0) {
                position -= startPosition;
                itemCount = dataSize;
                if (position >= itemCount) {
                    return;
                }
            } else {
                return;
            }
        }
        // parent.getChildCount() 是不断变化的 现在没办法保证最后一条
        // 保证第一条
        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager == null || layoutManager instanceof GridLayoutManager || layoutManager instanceof StaggeredGridLayoutManager) {
            return;
        }
        mOrientation = ((LinearLayoutManager) layoutManager).getOrientation();
        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
            if (!isShowLeft && position == 0) {
                left = 0;
            } else {
                if (isShowLine) {
                    left = size;
                } else {
                    left = 0;
                }
            }
            if (isShowRight && position == itemCount - 1) {
                right = size;
            }
            if (isShowTop) {
                top = size;
            }
            if (isShowBottom) {
                bottom = size;
            }
        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
            if (!isShowTop && position == 0) {
                top = 0;
            } else {
                if (isShowLine) {
                    top = size;
                } else {
                    top = 0;
                }
            }
            if (isShowBottom && position == itemCount - 1) {
                bottom = size;
            }
            if (isShowLeft) {
                left = size;
            }
            if (isShowRight) {
                right = size;
            }
        }
        outRect.set(left, top, right, bottom);
    }

    /**
     * 绘制分割线
     *
     * @param canvas
     * @param parent
     * @param state
     */
    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        mContext = null;
        if (mDivider == null) {
            return;
        } else if (size == 0) {
            return;
        }
        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
            drawHorizontalDividers(canvas, parent, state);
        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVerticalDividers(canvas, parent, state);
        }
    }

    /**
     * 绘制在图层的最上层
     *
     * @param canvas
     * @param parent
     * @param state
     */
    @Override
    public void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
    }

    /**
     * Adds dividers to a RecyclerView with a LinearLayoutManager or its
     * subclass oriented horizontally.
     *
     * @param canvas The {@link Canvas} onto which horizontal dividers will be
     *               drawn
     * @param parent The RecyclerView onto which horizontal dividers are being
     *               added
     */
    private void drawHorizontalDividers(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int childCount = parent.getChildCount();
        int itemCount = parent.getAdapter().getItemCount();
        int startPosition = -1;
        if (mItemDecorationListener != null) {
            startPosition = mItemDecorationListener.getStart();
            int dataSize = mItemDecorationListener.getDrawCount();
            if (startPosition >= 0 && dataSize > 0) {
                itemCount = dataSize;
            } else {
                return;
            }
        }
        int parentTop = parent.getPaddingTop() + marginLeft;
        if (isShowTop) {
            parentTop -= size;
        }
        int parentBottom = parent.getHeight() - parent.getPaddingBottom() - marginRight;
        if (isShowBottom) {
            parentBottom += size;
        }

        for (int i = 0; i < childCount; i++) {
            View childView = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(childView);

            if (mItemDecorationListener != null && startPosition >= 0) {
                if (position >= startPosition) {
                    position -= startPosition;
                } else {
                    continue;
                }
            }

            if (position < 0 || position >= itemCount) {
                continue;
            }

            if (isShowTop) {
                int left = childView.getLeft();
                int right = childView.getRight();
                if (isShowBottom) {
                    right += size;
                }
                int bottom = childView.getTop();
                int top = bottom - size;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (isShowBottom) {
                int left = childView.getLeft();
                int right = childView.getRight();
                if (isShowBottom) {
                    right += size;
                }
                int top = childView.getBottom();
                int bottom = top + size;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }

            if (isShowRight && position == itemCount - 1) {
                int parentLeft = childView.getRight();
                int parentRight = parentLeft + size;

                mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
                mDivider.draw(canvas);
            }

            if (!isShowLeft && position == 0) {
                continue;
            }

            if (isShowLine) {
                int parentRight = childView.getLeft();
                int parentLeft = parentRight - size;

                mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
                mDivider.draw(canvas);
            }
        }
    }

    /**
     * Adds dividers to a RecyclerView with a LinearLayoutManager or its
     * subclass oriented vertically.
     *
     * @param canvas The {@link Canvas} onto which vertical dividers will be
     *               drawn
     * @param parent The RecyclerView onto which vertical dividers are being
     *               added
     */
    private void drawVerticalDividers(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int childCount = parent.getChildCount();
        int itemCount = parent.getAdapter().getItemCount();
        int startPosition = -1;
        if (mItemDecorationListener != null) {
            startPosition = mItemDecorationListener.getStart();
            int dataSize = mItemDecorationListener.getDrawCount();
            if (startPosition >= 0 && dataSize > 0) {
                itemCount = dataSize;
            } else {
                return;
            }
        }
        int parentLeft = parent.getPaddingLeft() + marginLeft;
        if (isShowLeft) {
            parentLeft += size;
        }
        int parentRight = parent.getWidth() - parent.getPaddingRight() - marginRight;
        if (isShowRight) {
            parentLeft -= size;
        }

        for (int i = 0; i < childCount; i++) {
            View childView = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(childView);

            if (mItemDecorationListener != null && startPosition >= 0) {
                if (position >= startPosition) {
                    position -= startPosition;
                } else {
                    continue;
                }
            }

            if (position < 0 || position >= itemCount) {
                continue;
            }

            if (isShowLeft) {
                int top = childView.getTop();
                int bottom = childView.getBottom();
                if (isShowBottom) {
                    bottom += size;
                }
                int right = childView.getLeft();
                int left = right - size;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (isShowRight) {
                int top = childView.getTop();
                int bottom = childView.getBottom();
                if (isShowBottom) {
                    bottom += size;
                }
                int left = childView.getRight();
                int right = left + size;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }

            if (isShowBottom && position == itemCount - 1) {
                int parentTop = childView.getBottom();
                int parentBottom = parentTop + size;

                mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
                mDivider.draw(canvas);
            }

            if (!isShowTop && position == 0) {
                continue;
            }

            if (isShowLine) {
                int parentBottom = childView.getTop();
                int parentTop = parentBottom - size;
                mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
                mDivider.draw(canvas);
            }
        }
    }

}